﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPC.Communication.Framework.BasicFramework;
using IPC.Communication.Framework.Core;
using IPC.Communication.Framework.Core.IMessage;
using IPC.Communication.Framework.Core.Net;
using IPC.Communication.Framework.Reflection;

namespace IPC.Communication.Framework.Profinet.LSIS
{
    public class XGBFastEnet : NetworkDeviceBase
    {
        private string CompanyID1 = "LSIS-XGT";

        private LSCpuInfo cpuInfo = LSCpuInfo.XGK;

        private byte baseNo = 0;

        private byte slotNo = 3;

        public static string AddressTypes = "PMLKFTCDSQINUZR";

        public string SetCpuType
        {
            get;
            set;
        }

        public string CpuType
        {
            get;
            private set;
        }

        public bool CpuError
        {
            get;
            private set;
        }

        public LSCpuStatus LSCpuStatus
        {
            get;
            private set;
        }

        public byte BaseNo
        {
            get
            {
                return baseNo;
            }
            set
            {
                baseNo = value;
            }
        }

        public byte SlotNo
        {
            get
            {
                return slotNo;
            }
            set
            {
                slotNo = value;
            }
        }

        public LSCpuInfo CpuInfo
        {
            get
            {
                return cpuInfo;
            }
            set
            {
                cpuInfo = value;
            }
        }

        public string CompanyID
        {
            get
            {
                return CompanyID1;
            }
            set
            {
                CompanyID1 = value;
            }
        }

        public XGBFastEnet()
        {
            base.WordLength = 2;
            IpAddress = "127.0.0.1";
            Port = 2004;
            base.ByteTransform = new RegularByteTransform();
        }

        public XGBFastEnet(string ipAddress, int port)
            : this()
        {
            IpAddress = ipAddress;
            Port = port;
        }

        public XGBFastEnet(string CpuType, string ipAddress, int port, byte slotNo)
            : this(ipAddress, port)
        {
            SetCpuType = CpuType;
            this.slotNo = slotNo;
        }

        protected override INetMessage GetNewNetMessage()
        {
            return new LsisFastEnetMessage();
        }

        [HslMqttApi("ReadByteArray", "")]
        public override OperateResult<byte[]> Read(string address, ushort length)
        {
            OperateResult<byte[]> operateResult = BuildReadByteCommand(address, length);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(PackCommand(operateResult.Content));
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult2);
            }
            return ExtractActualData(operateResult2.Content);
        }

        [HslMqttApi("WriteByteArray", "")]
        public override OperateResult Write(string address, byte[] value)
        {
            OperateResult<byte[]> operateResult = BuildWriteByteCommand(address, value);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(PackCommand(operateResult.Content));
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult2);
            }
            return ExtractActualData(operateResult2.Content);
        }

        //[AsyncStateMachine(typeof(<ReadAsync>d__34))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
        //{
        //    <ReadAsync>d__34 stateMachine = new <ReadAsync>d__34();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__35))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, byte[] value)
        //{
        //    <WriteAsync>d__35 stateMachine = new <WriteAsync>d__35();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        [HslMqttApi("ReadBoolArray", "")]
        public override OperateResult<bool[]> ReadBool(string address, ushort length)
        {
            OperateResult<byte[]> operateResult = BuildReadByteCommand(address, length);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(PackCommand(operateResult.Content));
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult2);
            }
            OperateResult<byte[]> operateResult3 = ExtractActualData(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult3);
            }
            return OperateResult.CreateSuccessResult(SoftBasic.ByteToBoolArray(operateResult3.Content, length));
        }

        [HslMqttApi("ReadBool", "")]
        public override OperateResult<bool> ReadBool(string address)
        {
            OperateResult<byte[]> operateResult = BuildReadIndividualCommand(0, address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(PackCommand(operateResult.Content));
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool>(operateResult2);
            }
            OperateResult<byte[]> operateResult3 = ExtractActualData(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool>(operateResult3);
            }
            return OperateResult.CreateSuccessResult(SoftBasic.ByteToBoolArray(operateResult3.Content, 1)[0]);
        }

        public OperateResult<bool> ReadCoil(string address)
        {
            return ReadBool(address);
        }

        public OperateResult<bool[]> ReadCoil(string address, ushort length)
        {
            return ReadBool(address, length);
        }

        [HslMqttApi("ReadByte", "")]
        public OperateResult<byte> ReadByte(string address)
        {
            return ByteTransformHelper.GetResultFromArray(Read(address, 1));
        }

        [HslMqttApi("WriteByte", "")]
        public OperateResult Write(string address, byte value)
        {
            return Write(address, new byte[1]
		{
			value
		});
        }

        public OperateResult WriteCoil(string address, bool value)
        {
            return Write(address, new byte[2]
		{
			(byte)(value ? 1 : 0),
			0
		});
        }

        [HslMqttApi("WriteBool", "")]
        public override OperateResult Write(string address, bool value)
        {
            return WriteCoil(address, value);
        }

        //[AsyncStateMachine(typeof(<ReadBoolAsync>d__44))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<bool[]>> ReadBoolAsync(string address, ushort length)
        //{
        //    <ReadBoolAsync>d__44 stateMachine = new <ReadBoolAsync>d__44();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadBoolAsync>d__45))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<bool>> ReadBoolAsync(string address)
        //{
        //    <ReadBoolAsync>d__45 stateMachine = new <ReadBoolAsync>d__45();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadCoilAsync>d__46))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<bool>> ReadCoilAsync(string address)
        //{
        //    <ReadCoilAsync>d__46 stateMachine = new <ReadCoilAsync>d__46();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadCoilAsync>d__47))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<bool[]>> ReadCoilAsync(string address, ushort length)
        //{
        //    <ReadCoilAsync>d__47 stateMachine = new <ReadCoilAsync>d__47();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadByteAsync>d__48))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<byte>> ReadByteAsync(string address)
        //{
        //    <ReadByteAsync>d__48 stateMachine = new <ReadByteAsync>d__48();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__49))]
        //[DebuggerStepThrough]
        //public Task<OperateResult> WriteAsync(string address, byte value)
        //{
        //    <WriteAsync>d__49 stateMachine = new <WriteAsync>d__49();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteCoilAsync>d__50))]
        //[DebuggerStepThrough]
        //public Task<OperateResult> WriteCoilAsync(string address, bool value)
        //{
        //    <WriteCoilAsync>d__50 stateMachine = new <WriteCoilAsync>d__50();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__51))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, bool value)
        //{
        //    <WriteAsync>d__51 stateMachine = new <WriteAsync>d__51();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        private byte[] PackCommand(byte[] coreCommand)
        {
            byte[] array = new byte[coreCommand.Length + 20];
            Encoding.ASCII.GetBytes(CompanyID).CopyTo(array, 0);
            switch (cpuInfo)
            {
                case LSCpuInfo.XGK:
                    array[12] = 160;
                    break;
                case LSCpuInfo.XGI:
                    array[12] = 164;
                    break;
                case LSCpuInfo.XGR:
                    array[12] = 168;
                    break;
                case LSCpuInfo.XGB_MK:
                    array[12] = 176;
                    break;
                case LSCpuInfo.XGB_IEC:
                    array[12] = 180;
                    break;
            }
            array[13] = 51;
            BitConverter.GetBytes((short)coreCommand.Length).CopyTo(array, 16);
            array[18] = (byte)(baseNo * 16 + slotNo);
            int num = 0;
            for (int i = 0; i < 19; i++)
            {
                num += array[i];
            }
            array[19] = (byte)num;
            coreCommand.CopyTo(array, 20);
            string text = SoftBasic.ByteToHexString(array, ' ');
            return array;
        }

        public override string ToString()
        {
            return String.Format("XGBFastEnet[{0}:{1}]", IpAddress, Port);
        }

        public static int CalculateAddressStarted(string address, bool QI = false)
        {
            if (address.IndexOf('.') < 0)
            {
                return Convert.ToInt32(address);
            }
            string[] array = address.Split('.');
            if (!QI)
            {
                return Convert.ToInt32(array[0]);
            }
            if (array.Length >= 4)
            {
                return Convert.ToInt32(array[3]);
            }
            return Convert.ToInt32(array[2]);
        }

        private static bool IsHex(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return false;
            }
            bool result = false;
            for (int i = 0; i < value.Length; i++)
            {
                switch (value[i])
                {
                    case 'A':
                    case 'B':
                    case 'C':
                    case 'D':
                    case 'E':
                    case 'F':
                    case 'a':
                    case 'b':
                    case 'c':
                    case 'd':
                    case 'e':
                    case 'f':
                        result = true;
                        break;
                }
            }
            return result;
        }

        public static OperateResult<string> AnalysisAddress(string address, bool IsReadWrite)
        {
            StringBuilder stringBuilder = new StringBuilder();
            try
            {
                stringBuilder.Append("%");
                bool flag = false;
                if (IsReadWrite)
                {
                    for (int i = 0; i < AddressTypes.Length; i++)
                    {
                        if (AddressTypes[i] == address[0])
                        {
                            stringBuilder.Append(AddressTypes[i]);
                            char c = address[1];
                            char c2 = c;
                            if (c2 == 'X')
                            {
                                stringBuilder.Append("X");
                                if (address[0] == 'I' || address[0] == 'Q' || address[0] == 'U')
                                {
                                    stringBuilder.Append(CalculateAddressStarted(address.Substring(2), QI: true));
                                }
                                else if (IsHex(address.Substring(2)))
                                {
                                    stringBuilder.Append(address.Substring(2));
                                }
                                else
                                {
                                    stringBuilder.Append(CalculateAddressStarted(address.Substring(2)));
                                }
                            }
                            else
                            {
                                stringBuilder.Append("B");
                                int num = 0;
                                if (address[1] == 'B')
                                {
                                    num = ((address[0] != 'I' && address[0] != 'Q' && address[0] != 'U') ? CalculateAddressStarted(address.Substring(2)) : CalculateAddressStarted(address.Substring(2), QI: true));
                                    stringBuilder.Append((num == 0) ? num : (num *= 2));
                                }
                                else if (address[1] == 'W')
                                {
                                    num = ((address[0] != 'I' && address[0] != 'Q' && address[0] != 'U') ? CalculateAddressStarted(address.Substring(2)) : CalculateAddressStarted(address.Substring(2), QI: true));
                                    stringBuilder.Append((num == 0) ? num : (num *= 2));
                                }
                                else if (address[1] == 'D')
                                {
                                    num = CalculateAddressStarted(address.Substring(2));
                                    stringBuilder.Append((num == 0) ? num : (num *= 4));
                                }
                                else if (address[1] == 'L')
                                {
                                    num = CalculateAddressStarted(address.Substring(2));
                                    stringBuilder.Append((num == 0) ? num : (num *= 8));
                                }
                                else if (address[0] == 'I' || address[0] == 'Q' || address[0] == 'U')
                                {
                                    stringBuilder.Append(CalculateAddressStarted(address.Substring(1), QI: true));
                                }
                                else if (IsHex(address.Substring(1)))
                                {
                                    stringBuilder.Append(address.Substring(1));
                                }
                                else
                                {
                                    stringBuilder.Append(CalculateAddressStarted(address.Substring(1)));
                                }
                            }
                            flag = true;
                            break;
                        }
                    }
                }
                else
                {
                    stringBuilder.Append(address);
                    flag = true;
                }
                if (!flag)
                {
                    throw new Exception(StringResources.Language.NotSupportedDataType);
                }
            }
            catch (Exception ex)
            {
                return new OperateResult<string>(ex.Message);
            }
            return OperateResult.CreateSuccessResult(stringBuilder.ToString());
        }

        public static OperateResult<string> GetDataTypeToAddress(string address)
        {
            string value = string.Empty;
            try
            {
                char[] array = new char[12]
			{
				'P',
				'M',
				'L',
				'K',
				'F',
				'T',
				'C',
				'D',
				'S',
				'Q',
				'I',
				'R'
			};
                bool flag = false;
                for (int i = 0; i < array.Length; i++)
                {
                    if (array[i] == address[0])
                    {
                        switch (address[1])
                        {
                            case 'X':
                                value = "Bit";
                                break;
                            case 'W':
                                value = "Word";
                                break;
                            case 'D':
                                value = "DWord";
                                break;
                            case 'L':
                                value = "LWord";
                                break;
                            case 'B':
                                value = "Continuous";
                                break;
                            default:
                                value = "Continuous";
                                break;
                        }
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                {
                    throw new Exception(StringResources.Language.NotSupportedDataType);
                }
            }
            catch (Exception ex)
            {
                return new OperateResult<string>(ex.Message);
            }
            return OperateResult.CreateSuccessResult(value);
        }

        public static OperateResult<byte[]> BuildReadIndividualCommand(byte dataType, string address)
        {
            return BuildReadIndividualCommand(dataType, new string[1]
		{
			address
		});
        }

        public static OperateResult<byte[]> BuildReadIndividualCommand(byte dataType, string[] addresses)
        {
            MemoryStream memoryStream = new MemoryStream();
            memoryStream.WriteByte(84);
            memoryStream.WriteByte(0);
            memoryStream.WriteByte(dataType);
            memoryStream.WriteByte(0);
            memoryStream.WriteByte(0);
            memoryStream.WriteByte(0);
            memoryStream.WriteByte((byte)addresses.Length);
            memoryStream.WriteByte(0);
            foreach (string address in addresses)
            {
                OperateResult<string> operateResult = AnalysisAddress(address, IsReadWrite: true);
                if (!operateResult.IsSuccess)
                {
                    return OperateResult.CreateFailedResult<byte[]>(operateResult);
                }
                memoryStream.WriteByte((byte)operateResult.Content.Length);
                memoryStream.WriteByte(0);
                byte[] bytes = Encoding.ASCII.GetBytes(operateResult.Content);
                memoryStream.Write(bytes, 0, bytes.Length);
            }
            return OperateResult.CreateSuccessResult(memoryStream.ToArray());
        }

        private static OperateResult<byte[]> BuildReadByteCommand(string address, ushort length)
        {
            OperateResult<string> operateResult = AnalysisAddress(address, IsReadWrite: true);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            OperateResult<string> dataTypeToAddress = GetDataTypeToAddress(address);
            if (!dataTypeToAddress.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(dataTypeToAddress);
            }
            byte[] array = new byte[12 + operateResult.Content.Length];
            switch (dataTypeToAddress.Content)
            {
                case "Bit":
                    array[2] = 0;
                    break;
                case "Word":
                case "DWord":
                case "LWord":
                case "Continuous":
                    array[2] = 20;
                    break;
            }
            array[0] = 84;
            array[1] = 0;
            array[2] = 0;
            array[3] = 0;
            array[4] = 0;
            array[5] = 0;
            array[6] = 1;
            array[7] = 0;
            array[8] = (byte)operateResult.Content.Length;
            array[9] = 0;
            Encoding.ASCII.GetBytes(operateResult.Content).CopyTo(array, 10);
            BitConverter.GetBytes(length).CopyTo(array, array.Length - 2);
            return OperateResult.CreateSuccessResult(array);
        }

        private OperateResult<byte[]> BuildWriteByteCommand(string address, byte[] data)
        {
            string setCpuType = SetCpuType;
            string a = setCpuType;
            OperateResult<string> operateResult = (a == "XGK") ? AnalysisAddress(address, IsReadWrite: true) : ((!(a == "XGB")) ? AnalysisAddress(address, IsReadWrite: true) : AnalysisAddress(address, IsReadWrite: false));
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            OperateResult<string> dataTypeToAddress = GetDataTypeToAddress(address);
            if (!dataTypeToAddress.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(dataTypeToAddress);
            }
            byte[] array = new byte[12 + operateResult.Content.Length + data.Length];
            switch (dataTypeToAddress.Content)
            {
                case "Bit":
                case "Byte":
                    array[2] = 1;
                    break;
                case "Word":
                    array[2] = 2;
                    break;
                case "DWord":
                    array[2] = 3;
                    break;
                case "LWord":
                    array[2] = 4;
                    break;
                case "Continuous":
                    array[2] = 20;
                    break;
            }
            array[0] = 88;
            array[1] = 0;
            array[3] = 0;
            array[4] = 0;
            array[5] = 0;
            array[6] = 1;
            array[7] = 0;
            array[8] = (byte)operateResult.Content.Length;
            array[9] = 0;
            Encoding.ASCII.GetBytes(operateResult.Content).CopyTo(array, 10);
            BitConverter.GetBytes(data.Length).CopyTo(array, array.Length - 2 - data.Length);
            data.CopyTo(array, array.Length - data.Length);
            return OperateResult.CreateSuccessResult(array);
        }

        public OperateResult<byte[]> ExtractActualData(byte[] response)
        {
            if (response.Length < 20)
            {
                return new OperateResult<byte[]>("Length is less than 20:" + SoftBasic.ByteToHexString(response));
            }
            ushort num = BitConverter.ToUInt16(response, 10);
            BitArray bitArray = new BitArray(BitConverter.GetBytes(num));
            int num2 = (int)num % 32;
            switch ((int)num % 32)
            {
                case 1:
                    CpuType = "XGK/R-CPUH";
                    break;
                case 2:
                    CpuType = "XGK-CPUS";
                    break;
                case 4:
                    CpuType = "XGK-CPUE";
                    break;
                case 5:
                    CpuType = "XGK/R-CPUH";
                    break;
                case 6:
                    CpuType = "XGB/XBCU";
                    break;
            }
            CpuError = bitArray[7];
            if (bitArray[8])
            {
                LSCpuStatus = LSCpuStatus.RUN;
            }
            if (bitArray[9])
            {
                LSCpuStatus = LSCpuStatus.STOP;
            }
            if (bitArray[10])
            {
                LSCpuStatus = LSCpuStatus.ERROR;
            }
            if (bitArray[11])
            {
                LSCpuStatus = LSCpuStatus.DEBUG;
            }
            if (response.Length < 28)
            {
                return new OperateResult<byte[]>("Length is less than 28:" + SoftBasic.ByteToHexString(response));
            }
            ushort num3 = BitConverter.ToUInt16(response, 26);
            if (num3 > 0)
            {
                return new OperateResult<byte[]>(response[28], "Error:" + GetErrorDesciption(response[28]));
            }
            if (response[20] == 89)
            {
                return OperateResult.CreateSuccessResult(new byte[0]);
            }
            if (response[20] == 85)
            {
                try
                {
                    ushort num4 = BitConverter.ToUInt16(response, 30);
                    byte[] array = new byte[num4];
                    Array.Copy(response, 32, array, 0, num4);
                    return OperateResult.CreateSuccessResult(array);
                }
                catch (Exception ex)
                {
                    return new OperateResult<byte[]>(ex.Message);
                }
            }
            return new OperateResult<byte[]>(StringResources.Language.NotSupportedFunction);
        }

        public static string GetErrorDesciption(byte code)
        {
            switch (code)
            {
                case 0:
                    return "Normal";
                case 1:
                    return "Physical layer error (TX, RX unavailable)";
                case 3:
                    return "There is no identifier of Function Block to receive in communication channel";
                case 4:
                    return "Mismatch of data type";
                case 5:
                    return "Reset is received from partner station";
                case 6:
                    return "Communication instruction of partner station is not ready status";
                case 7:
                    return "Device status of remote station is not desirable status";
                case 8:
                    return "Access to some target is not available";
                case 9:
                    return "Can’ t deal with communication instruction of partner station by too many reception";
                case 10:
                    return "Time Out error";
                case 11:
                    return "Structure error";
                case 12:
                    return "Abort";
                case 13:
                    return "Reject(local/remote)";
                case 14:
                    return "Communication channel establishment error (Connect/Disconnect)";
                case 15:
                    return "High speed communication and connection service error";
                case 33:
                    return "Can’t find variable identifier";
                case 34:
                    return "Address error";
                case 50:
                    return "Response error";
                case 113:
                    return "Object Access Unsupported";
                case 187:
                    return "Unknown error code (communication code of other company) is received";
                default:
                    return "Unknown error";
            }
        }
    }
}